<template>
	<div class="tool-title-box custom-box">
		<h3>格栅布局</h3>
		<div class="operation-box">
			<div class="item-box">
				<div class="title">选择布局</div>
				<div class="modify-box">
					<el-select v-model="activeComponent.data.layoutType" placeholder="请选择" @change="onLayoutTypeChange" class="w100">
						<el-option v-for="(item, index) in layoutList" :key="index" :label="item.name" :value="item.type"></el-option>
					</el-select>
				</div>
			</div>
			<div class="item-box flex-style">
				<div class="title">布局高度</div>
				<div class="block">
					<el-slider :show-input-controls="false" input-size="mini" :max="1000" v-model="activeComponent.data.layoutHeight" show-input></el-slider>
				</div>
			</div>
			<div v-if="activeComponent.data.layoutType == 'average'" class="item-box">
				<div class="title">布局密度</div>
				<div class="modify-box">
					<el-select v-model="activeComponent.data.density" placeholder="请选择" @change="onDensityChange" class="w100">
						<el-option v-for="item in densityOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
					</el-select>
				</div>
			</div>
			<div class="item-box">
				<div v-if="activeComponent.data.layoutType !== 'average'" style="margin: 0 auto;">
					<p class="text-tips w100">选定布局区域，可以在布局下方添加与布局一致的等比例的图片，或者拖拽左侧组件到布局区域中。</p>
					<div class="layout-box" :class="activeComponent.data.layoutType">
						<div class="item" v-for="index of activeComponent.data.elementNum" :key="index"
							:class="{active: activeComponent.data.activeIndex === index-1}" 
							:style="{
								'backgroundColor': activeComponent.data.children[index-1].bgColor, 
								'backgroundImage': `url('${activeComponent.data.children[index-1].imageUrl}')`, 
								'backgroundRepeat': 'no-repeat',
								'backgroundSize': 'contain',
								'backgroundPosition': 'top'}"
							@click="selectLayout(index-1)">
							<!-- 布局占位 -->
						</div>
					</div>
				</div>
				<div v-else style="margin: 0 auto;">
					<p class="text-tips w100">先点击后移动鼠标，再次点击确定布局区域，选定布局区域，可以在布局下方添加与布局一致的等比例的图片，或者拖拽左侧组件到布局区域中。</p>
					<div class="average-box-warp">
						<div class="average-box" @mouseleave="onAverageBoxLeave">
							<ul v-for="i of parseInt(activeComponent.data.density)" :key="`y-${i}`" :class="`col${activeComponent.data.density}`">
								<li v-for="j of parseInt(activeComponent.data.density)" :key="`x-${j}`"
									:class="{'on':activeComponent.data.averageBoxData[i-1][j-1].hover}"
									@click="onAverageBoxClick(i-1,j-1)" @mouseover="onAverageBoxMouseover(i-1,j-1)">
								</li>
							</ul>
						</div>
						<div class="selected-cube">
							<ul>
								<li v-for="(item,index) of activeComponent.data.children" :key="index"
									:class="{active: activeComponent.data.activeIndex === index}"
									:style="{'width':getItemValue(item.width) + '%','height':getItemValue(item.height) + '%','left':getItemValue(item.left) + '%','top':getItemValue(item.top) + '%'}">
									<div class="box" 
										:style="{
											'backgroundColor': activeComponent.data.children[index].bgColor,
											'backgroundImage': `url('${activeComponent.data.children[index].imageUrl}')`, 
											'backgroundRepeat': 'no-repeat',
											'backgroundSize': 'contain',
											'backgroundPosition': 'top'}"
										@click="selectLayout(index)">
										<!-- 布局占位 -->
									</div>
									<a class="btn-close" @click="delSlectedCube(item,index)">
										<i class="fa fa-times" aria-hidden="true"></i>
									</a>
								</li>
							</ul>
						</div>
					</div>
				</div>
			</div>
			<div class="item-box" v-if="activeComponent.data.activeIndex >= 0">
				<div class="title">背景颜色</div>
				<div class="info">{{activeComponent.data.children[activeComponent.data.activeIndex].bgColor}}</div>
				<div class="modify-box">
					<div class="color-box">
						<span @click="activeComponent.data.children[activeComponent.data.activeIndex].bgColor = ''">重置</span>
						<div class="block">
							<el-color-picker v-model="activeComponent.data.children[activeComponent.data.activeIndex].bgColor"></el-color-picker>
						</div>
					</div>
				</div>
			</div>
			<tool-single-img v-if="activeComponent.data.activeIndex >= 0" v-model:imageUrl="activeComponent.data.children[activeComponent.data.activeIndex].imageUrl" tip="适合布局尺寸等比例图片, 高度自适应"></tool-single-img>
			
		</div>
	</div>
</template>

<script lang="ts">
	import { toRefs, reactive, onMounted, computed, } from 'vue';
	import { useStore } from '/@/store/index';
	
	import ToolSingleImg from '/@/views/decorator/components/toolBar/module/tool-single-img.vue';
	export default {
		name: 'custom-tool',
		components: {
			ToolSingleImg,
		},
		setup() {
			const store = useStore();
			const state = reactive({
				title: '', // 标题内容
				imageUrl: '', // 图片地址
				linkValue: '', // 链接地址
				layoutList: [{
						id: 0,
						type: 'L1',
						name: '一行一列',
						number: 1, // 显示格子数
					},
					{
						id: 1,
						type: 'L2',
						name: '一行二列',
						number: 2, // 显示格子数
					},
					{
						id: 2,
						type: 'L3',
						name: '一行三列',
						number: 3,
					},
					{
						id: 3,
						type: 'L4',
						name: '一行四列',
						number: 4,
					},
					{
						id: 8,
						type: 'average',
						name: '自定义布局',
						number: 0,
					}
				],
				densityOptions: [
					{
						value: 3,
						label: "3 * 3"
					},
					{
						value: 4,
						label: "4 * 4"
					},
					{
						value: 6,
						label: "6 * 6"
					},
					{
						value: 10,
						label: "10 * 10"
					},
					{
						value: 20,
						label: "20 * 20"
					},
				],
				elementNum: 2, // 生成格子数量
				beginAverageBox: [], // 记录开始点击的格子
				endAverageBox: [], // 记录结束点击的格子
			})
			
			state.terminal = computed(() => store.state.decorator.terminal);
			state.activeComponent = computed(() => store.state.decorator.activeComponent);
			
			// 计算生成格子百分比
			const getItemValue = (val) => {
				const density = parseInt(state.activeComponent.data.density)
				return (val === 0 || density === 0) ? 0 : (val / density * 10000 / 100.00) // 小数点后两位百分比
			}
			
			// 选择布局
			const selectLayout = (index) => {
				state.activeComponent.data.activeIndex = index;
			}
			
			// 选择布局类型
			const onLayoutTypeChange = (val) => {
				let item = state.layoutList.filter(item => item.type == val)[0];
				state.activeComponent.data.activeIndex = 0;
				state.activeComponent.data.elementNum = item.number;
				state.activeComponent.data.layoutType = item.type;
				state.activeComponent.data.layoutHeight = 100;
				if (item.type === 'average') {
					//自定义布局
					onDensityChange(state.activeComponent.data.density);
				} else {
					let length = state.activeComponent.data.children.length;
					let count = item.number - length;
					if(count >= 0){
						for (let i = 0; i < count; i++) {
							state.activeComponent.data.children.push({
								bgColor: '',
								imageUrl: '',
								componentsData: [],
							});
						}
					}else{
						state.activeComponent.data.children.splice(-1, -count);
					}
				}
			}
			
			// 切换密度
			const onDensityChange = (density) => {
				state.activeComponent.data.activeIndex = -1;
				state.activeComponent.data.averageBoxData = [];
				state.activeComponent.data.layoutHeight = 100;
				for (let i = 0; i < density; i++) {
					state.activeComponent.data.averageBoxData[i] = [];
					for (let j = 0; j < density; j++) {
						state.activeComponent.data.averageBoxData[i].push({
							hover: false, // 判断经过激活的位置
							takeUp: false // 判断占击占用的位置
						});
					}
				}
				state.activeComponent.data.children = [];
			}
			// 自定义布局格子点击
			const onAverageBoxClick = (x, y) => {
				if (state.beginAverageBox.length === 0) {
					state.beginAverageBox = [x, y];
					state.endAverageBox = [x, y];
					state.activeComponent.data.averageBoxData[x][y].hover = true;
					let arrays = state.activeComponent.data.averageBoxData.concat([]); // 触发视图更新
					state.activeComponent.data.averageBoxData = arrays;
				} else {
					const bx = state.beginAverageBox[0]; // 起点X
					const by = state.beginAverageBox[1]; // 起点Y
					// 使用最后一次合理经过的位置
					x = state.endAverageBox[0];
					y = state.endAverageBox[1];
					// 计算占用位置
					if (x >= bx) {
						for (let i = bx; i <= x; i++) {
							if (y >= by) {
								for (let j = by; j <= y; j++) {
									state.activeComponent.data.averageBoxData[i][j].takeUp = true;
								}
							} else {
								for (let j = y; j <= by; j++) {
									state.activeComponent.data.averageBoxData[i][j].takeUp = true;
								}
							}
						}
					} else {
						for (let i = x; i <= bx; i++) {
							if (y >= by) {
								for (let j = by; j <= y; j++) {
									state.activeComponent.data.averageBoxData[i][j].takeUp = true;
								}
							} else {
								for (let j = y; j <= by; j++) {
									state.activeComponent.data.averageBoxData[i][j].takeUp = true;
								}
							}
						}
					}
					
					// 生成图片框
					const data = {
						bgColor: '',
						imageUrl: '',
						componentsData: [],
					}
					if (x >= bx) {
						data.width = x - bx + 1
						data.left = bx
					} else {
						data.width = bx - x + 1
						data.left = x
					}
					if (y >= by) {
						data.height = y - by + 1
						data.top = by
					} else {
						data.height = by - y + 1
						data.top = y
					}
					
					state.beginAverageBox = [];
					state.activeComponent.data.children.push(data);
				}
			}
			// 自定义格子经过
			const onAverageBoxMouseover = (x, y) => {
				if (state.beginAverageBox.length !== 0) {
					// 计算有没有经过有占用的位置
					let flag = isBoxTakeUp(x, y);
					if (!flag) {
						return false
					}
					// 每次经过洗白格子
					const bx = state.beginAverageBox[0]; // 起点X
					const by = state.beginAverageBox[1]; // 起点Y
					const densityVal = parseInt(state.activeComponent.data.density);
					for (let i = 0; i < densityVal; i++) {
						for (let j = 0; j < densityVal; j++) {
							state.activeComponent.data.averageBoxData[i][j].hover = false;
						}
					}
					state.activeComponent.data.averageBoxData[x][y].hover = true;
					// 起终点中间位置激活
					if (x >= bx) {
						for (let i = bx; i <= x; i++) {
							if (y >= by) {
								for (let j = by; j <= y; j++) {
									state.activeComponent.data.averageBoxData[i][j].hover = true
								}
							} else {
								for (let j = y; j <= by; j++) {
									state.activeComponent.data.averageBoxData[i][j].hover = true
								}
							}
						}
					} else {
						for (let i = x; i <= bx; i++) {
							if (y >= by) {
								for (let j = by; j <= y; j++) {
									state.activeComponent.data.averageBoxData[i][j].hover = true
								}
							} else {
								for (let j = y; j <= by; j++) {
									state.activeComponent.data.averageBoxData[i][j].hover = true
								}
							}
						}
					}
					state.endAverageBox = [x, y]; // 记录结束位置
					let arrays = state.activeComponent.data.averageBoxData.concat([]); // 触发视图更新
					state.activeComponent.data.averageBoxData = arrays;
				}
			}
			// 计算有没有经过有占用的位置
			const isBoxTakeUp = (x, y) => {
				if (state.beginAverageBox.length !== 0) {
					const bx = state.beginAverageBox[0] // 起点X
					const by = state.beginAverageBox[1] // 起点Y
					let flag = true
					if (x >= bx) {
						for (let i = bx; i <= x; i++) {
							if (y >= by) {
								for (let j = by; j <= y; j++) {
									if (state.activeComponent.data.averageBoxData[i][j].takeUp) {
										flag = false
										break
									}
								}
							} else {
								for (let j = y; j <= by; j++) {
									if (state.activeComponent.data.averageBoxData[i][j].takeUp) {
										flag = false
										break
									}
								}
							}
						}
					} else {
						for (let i = x; i <= bx; i++) {
							if (y >= by) {
								for (let j = by; j <= y; j++) {
									if (state.activeComponent.data.averageBoxData[i][j].takeUp) {
										flag = false
										break
									}
								}
							} else {
								for (let j = y; j <= by; j++) {
									if (state.activeComponent.data.averageBoxData[i][j].takeUp) {
										flag = false
										break
									}
								}
							}
						}
					}
					return flag
				}
			}
			// 移出盒子清空
			const onAverageBoxLeave = () => {
				state.beginAverageBox = [];
				state.endAverageBox = [];
				const densityVal = parseInt(state.activeComponent.data.density)
				for (let i = 0; i < densityVal; i++) {
					for (let j = 0; j < densityVal; j++) {
						state.activeComponent.data.averageBoxData[i][j].hover = false;
					}
				}
			}
			// 删除选中格子
			const delSlectedCube = (item, index) => {
				// 清除占用位置
				let bx = item.left;
				let by = item.top;
				let xl = item.width;
				let yl = item.height;
				for (let i = bx; i < bx + xl; i++) {
					for (let j = by; j < by + yl; j++) {
						state.activeComponent.data.averageBoxData[i][j].takeUp = false;
					}
				}
				state.activeComponent.data.activeIndex = -1;
				state.activeComponent.data.children.splice(index, 1);
			}
			
			onMounted(() => {
				
			})
			
			return {
				onLayoutTypeChange,
				onDensityChange,
				onAverageBoxClick,
				onAverageBoxMouseover,
				onAverageBoxLeave,
				delSlectedCube,
				getItemValue,
				selectLayout,
				...toRefs(state),
			};
		},
	}
</script>

<style lang="scss" scoped>
@import './scss/index.scss';
.custom-box {
	.layout-box {
		margin-top: 15px;
		display: flex;

		.item {
			margin: -1px 0 0 -1px;
			flex: 0 0 50%;
			height: 100px;
			border: 1px solid #E8EAEC;
			box-sizing: border-box;
			display: flex;
			align-items: center;
			justify-content: center;
			cursor: pointer;
			position: relative;

			&:before {
				font-size: 12px;
				color: #666666;
				padding: 0 10px;
				text-align: center;
			}

			.img {
				position: absolute;
				width: 100%;
				height: 100%;
				left: 0;
				top: 0;
			}

			&.active {
				background: #FBF9F8;

				&:before {
					color: #409EFF;
				}

				&:after {
					content: '';
					width: 100%;
					height: 100%;
					border: 1px solid #409EFF;
					position: absolute;
					left: 0;
					top: 0;
					z-index: 2;
				}
			}
		}
	}

	.text-tips {
		line-height: 24px;
		font-size: 12px;
		color: #666666;
	}

	.L1 {
		.item {
			flex: 0 0 100%;
			height: 100px;

			&:before {
			}
		}
	}

	.L2 {
		.item {
			flex: 0 0 50%;
			height: 100px;

			&:before {
			}
		}
	}

	.L3 {
		.item {
			flex: 0 0 33.3%;
			height: 100px;

			&:before {
			}
		}
	}

	.L4 {
		.item {
			flex: 0 0 25%;
			height: 100px;

			&:before {
			}
		}
	}

	.average {
		flex-wrap: wrap;

		.item {
			flex: 0 0 33.33%;
			height: 93px;
		}
	}

	.average-box-warp {
		position: relative;
	}

	.average-box {
		margin-top: 15px;
		display: flex;
		flex-wrap: wrap;

		ul {
			list-style: none;
			li {
				margin: -1px 0 0 -1px;
				border: 1px solid #E8EAEC;
				background-color: #f8f8f8;
				list-style: none;
				&.on {
					background-color: var(--color-primary-light-6);
				}
			}
			
			&.col3 {
				flex: 0 0 33.33%;

				li {
					height: 66.66px;
				}
			}
			
			&.col4 {
				flex: 0 0 25%;

				li {
					height: 50px;
				}
			}

			&.col6 {
				flex: 0 0 16.6%;

				li {
					height: 33.33px;
				}
			}

			&.col10 {
				flex: 0 0 10%;

				li {
					height: 20px;
				}
			}
			
			&.col20 {
				flex: 0 0 5%;
			
				li {
					height: 10px;
				}
			}
		}
	}

	.selected-cube {
		li {
			list-style: none;
			position: absolute;
			font-size: 12px;
			border: 1px solid #E8EAEC;
			background-color: #fff;
			z-index: 2;
			margin: -1px 0 0 -1px;
			box-sizing: content-box;

			.box {
				width: 100%;
				height: 100%;
				display: flex;
				justify-content: center;
				align-items: center;
				cursor: pointer;
			}

			.img {
				position: absolute;
				width: 100%;
				height: 100%;
				left: 0;
				top: 0;
			}

			.btn-close {
				position: absolute;
				top: 0px;
				right: 2px;
				z-index: 4;
				cursor: pointer;
				display: none;
				i {
					color: var(--color-primary);
				}
			}

			&.active {
				z-index: 3;
				background: #FBF9F8;

				&:hover {
					.btn-close {
						display: block;
					}
				}

				span {
					color: #409EFF;
				}

				&:after {
					content: '';
					width: 100%;
					height: 100%;
					border: 1px solid #409EFF;
					position: absolute;
					left: 0;
					top: 0;
					z-index: 2;
				}
			}
		}
	}
}
.tool-title-box {
	&.custom-box {
		.operation-box {
			.item-box {
				.layout-box {
					.item {
						&:before {
							content: '1';
						}
					}
				}

				.L1 {
					.item {
						&:before {
							content: '1';
						}
					}
				}

				.L3 {
					.item {
						&:before {
							content: '1';
						}
					}
				}

				.L4 {
					.item {
						&:before {
							content: '1';
						}
					}
				}
			}
		}
	}
}
</style>
